#include "groupmodel.hpp"
#include "db.h"

#include <sstream>  // for std::ostringstream

// 创建群组
bool GroupModel::createGroup(Group &group)
{
    // 1.组装sql语句
    std::stringstream sql;
    // 因为AllGroup表内的ID字段是自增的， 所以没加id
    sql << "insert into AllGroup(groupname, groupdesc) values('" 
        << group.getName() << "', '" << group.getDesc() << "')";
    MySQL mysql;
    if (mysql.connect()) {
        if (mysql.update(sql.str()))
        {
            // 通过&group引用, 把新的主键ID写到实参
            group.setId(mysql_insert_id(mysql.getConnection()));
            return true;
        }
    }
    return false;
}

// 加入群组
void GroupModel::addGroup(int userid, int groupid, std::string role)
{
    // 1.组装sql语句
    std::ostringstream sql;
    sql << "insert into GroupUser values(" << groupid << ", " << userid << ", '" << role << "')";
    
    MySQL mysql;
    if (mysql.connect()) {
        mysql.update(sql.str());
    }
}

// 查询用户所在的群组信息
std::vector<Group> GroupModel::queryGroups(int userid)
{
    // 1.先根据userid在GroupUser表中查询该用户所属的群信息
    /* mysql> desc AllGroup;    表包含所有群组的信息。
    +-----------+--------------+------+-----+---------+----------------+
    | Field     | Type         | Null | Key | Default | Extra          |
    +-----------+--------------+------+-----+---------+----------------+
    | id        | int          | NO   | PRI | NULL    | auto_increment |
    | groupname | varchar(50)  | NO   |     | NULL    |                |
    | groupdesc | varchar(200) | YES  |     |         |                |
    +-----------+--------------+------+-----+---------+----------------+*/
       /* mysql> desc GroupUser;    用于表示用户和群组之间的关系，即哪些用户属于哪些群组。
        +-----------+--------------------------+------+-----+---------+-------+
        | Field     | Type                     | Null | Key | Default | Extra |
        +-----------+--------------------------+------+-----+---------+-------+
        | groupid   | int                      | NO   | PRI | NULL    |       |
        | userid    | int                      | NO   |     | NULL    |       |
        | grouprole | enum('creator','normal') | YES  |     | normal  |       |
        +-----------+--------------------------+------+-----+---------+-------+ */
    // 1.组织sql语句
    std::ostringstream sql;
    // 多表联合查询
    sql << "select a.id, a.groupname, a.groupdesc from AllGroup a inner join GroupUser b on a.id = b.groupid where b.userid = " << userid;
    // 1.2用来保住所以的群信息
    std::vector<Group> groupVec;
    // 2.数据库操作
    MySQL mysql;
    // 2.1数据库连接
    if (mysql.connect()) {
        // 2.2数据库查询
        MYSQL_RES * res = mysql.query(sql.str());
        if (res != nullptr) {
            MYSQL_ROW row;
            // 2.3获得每一个组的信息
            while ((row = mysql_fetch_row(res)) != nullptr) {
                Group group;
                group.setId(std::stoi(row[0]));
                group.setName(row[1]);
                group.setDesc(row[2]);
                groupVec.push_back(group);
            }
            // 2.4释放结果集
            mysql_free_result(res);        
        }        
    }
    // 3挨个遍历每一个群
    for (Group &group : groupVec) {
        sql.str("");
        /* mysql> desc User;
        +----------+--------------------------+------+-----+---------+----------------+
        | Field    | Type                     | Null | Key | Default | Extra          |
        +----------+--------------------------+------+-----+---------+----------------+
        | id       | int                      | NO   | PRI | NULL    | auto_increment |
        | name     | varchar(50)              | NO   | UNI | NULL    |                |
        | password | varchar(50)              | NO   |     | NULL    |                |
        | state    | enum('online','offline') | YES  |     | offline |                |
        +----------+--------------------------+------+-----+---------+----------------+ */
        /* mysql> desc GroupUser;
        +-----------+--------------------------+------+-----+---------+-------+
        | Field     | Type                     | Null | Key | Default | Extra |
        +-----------+--------------------------+------+-----+---------+-------+
        | groupid   | int                      | NO   | PRI | NULL    |       |
        | userid    | int                      | NO   |     | NULL    |       |
        | grouprole | enum('creator','normal') | YES  |     | normal  |       |
        +-----------+--------------------------+------+-----+---------+-------+ */
        // 3.1组织sql语句： 查询每一个gid下的群员信息
        sql << "select a.id, a.name, a.state, b.grouprole from User a inner join GroupUser b on b.userid = a.id, where b.groupid = "
            << group.getGId();
        // 3.2查询
        MYSQL_RES * res = mysql.query(sql.str());
        if (res != nullptr) {
            MYSQL_ROW row;
            while ((row = mysql_fetch_row(res)) != nullptr) {
                // 3.3写入每一个群员到Group::_users 容器中
                GroupUser groupuser;
                groupuser.setId(std::stoi(row[0]));
                groupuser.setName(row[1]);
                groupuser.setState(row[2]);
                groupuser.setRole(row[3]);
                group.getUser().push_back(groupuser);
            }
            // 3.4释放结果集
            mysql_free_result(res);
        }
    }
    return groupVec;
}

// 通过groupid查询群组用户id列表, 除userid自己， 用户群聊天业务给群组其他成员群发消息
std::vector<int> GroupModel::queryGroupUsers(int userid, int groupid)
{
    std::stringstream sql;
    /* mysql> desc GroupUser;
    +-----------+--------------------------+------+-----+---------+-------+
    | Field     | Type                     | Null | Key | Default | Extra |
    +-----------+--------------------------+------+-----+---------+-------+
    | groupid   | int                      | NO   | PRI | NULL    |       |
    | userid    | int                      | NO   |     | NULL    |       |
    | grouprole | enum('creator','normal') | YES  |     | normal  |       |
    +-----------+--------------------------+------+-----+---------+-------+ */
    // 1.组织sql语句
    sql << "select userid from GroupUser where groupid = " << groupid
        << " and userid != " << userid;
    std::vector<int> idVec;
    // 2.数据库连接
    MySQL mysql;
    if (mysql.connect()) {
        // 3.查询结果集不为空
        MYSQL_RES * res = mysql.query(sql.str());
        if (res != nullptr) {
            MYSQL_ROW row;
            // 4.提取结果集中的群员id号
            while((row = mysql_fetch_row(res)) != nullptr) {
                idVec.push_back(std::stoi(row[0]));
            }
            // 5.释放结果集
            mysql_free_result(res);
        }
    }
    return idVec;
}
